package org.dbp.filtro;

import java.util.ArrayList;
import java.util.List;

import org.dbp.error.ErrorDbpUtils;
import org.dbp.error.exception.ExceptionDbp;
import org.dbp.filtro.bean.FiltroCriterio;
import org.dbp.filtro.bean.enums.OperadorRelacional;
import org.dbp.filtro.bean.enums.TipoOperacionFiltro;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * Esta clase la utilizamos, para crear un listado de criterios, con un dsl.
 * 
 *  Contempla las siguientes tipos de operaciones:
 *  
 *  	- A�adir un criterio.
 *  	- La operaci�n Y.
 *  	- La operaci�n O.
 *  	- Limpiar la lista.
 *  	- Obtener el listado.
 * 
 * @author David Blanco Par�s
 *
 */
public class CriterioFactoria {

	private Logger logger = LoggerFactory.getLogger(CriterioFactoria.class);
	
	public static final String mensajeErrorNoSePuedeAplicarOperacionIzquiera="criteriofactoria.mensaje.error.noSePuedeAplicarOperacionIzquiera"; 
	
	// Errores de a�adir el criterio
	public static final String mensajeErrorAddCriterioOperacionNoValida="criteriofactoria.mensaje.error.addCriterioOperacionNoValida";
	public static final String mensajeErrorAddCriterioCampoNoValido    ="criteriofactoria.mensaje.error.addCriterioCampoNoValido";
	public static final String mensajeErrorAddCriterioValorNoValido    ="criteriofactoria.mensaje.error.addCriterioValorNoValido";
	
	private List<FiltroCriterio> listadoDeCriterios = null;
	/**
	 * 
	 * A�adimos un criterio para los filtros y se encadena con el siguiente con un or..
	 * 
	 * @param operacion	La operacio que vamos aplicar como filtro.
	 * @param campo		El campo sobre el que vamos aplicar el valor.
	 * @param valor		El valor de filtrado.
	 * @return
	 * @throws ExceptionDbp 
	 */
	public CriterioFactoria addCriterio(TipoOperacionFiltro operacion,String campo,String valor) throws ExceptionDbp{
		if(listadoDeCriterios==null){
			listadoDeCriterios=new ArrayList<FiltroCriterio>();
		}
		if(operacion==null){
			ErrorDbpUtils.obtenerInstancia().procesarErrorClave(logger, 
					mensajeErrorAddCriterioOperacionNoValida,operacion);
		}else if(campo==null){
			ErrorDbpUtils.obtenerInstancia().procesarErrorClave(logger, 
					mensajeErrorAddCriterioCampoNoValido,campo);
		}else if(valor==null){
			ErrorDbpUtils.obtenerInstancia().procesarErrorClave(logger, 
					mensajeErrorAddCriterioValorNoValido,valor);
			
		}
		FiltroCriterio filtro = new FiltroCriterio();
		filtro.setOperacion(operacion);
		filtro.setCampo(campo);
		filtro.setValorFiltro(valor);
		filtro.setRelacional(OperadorRelacional.O);
		listadoDeCriterios.add(filtro);
		return this;
	}
	/**
	 * 
	 * Lo que hace es limpiar la lista de criterios.
	 * 
	 * @return
	 */
	public CriterioFactoria limpiarCondiciones(){
		this.listadoDeCriterios=null;
		return this;
	}
	
	/**
	 * A�adimo el operador Y por la derecha.
	 * @return
	 * @throws ExceptionDbp
	 */
	public CriterioFactoria y() throws ExceptionDbp{
		return establecerOperadorRelacional(OperadorRelacional.Y);
	}
	/**
	 * A�adimos el operador por la derecha.
	 * @return
	 * @throws ExceptionDbp
	 */
	public CriterioFactoria o() throws ExceptionDbp{
		return establecerOperadorRelacional(OperadorRelacional.O);
	}
	
	/**
	 * 
	 * Le indicamos el operador relaciona al ultimo elemento.
	 * 
	 * @param operacion			Le pasamos el operador que nos interesa pasar.
	 * @throws ExceptionDbp
	 */
	private CriterioFactoria establecerOperadorRelacional(OperadorRelacional operacion)
			throws ExceptionDbp {
		if(listadoDeCriterios==null 
				|| listadoDeCriterios.size()==0){
			logger.error("No se puede aplicar una operaci�n, ");
			ErrorDbpUtils.obtenerInstancia().procesarErrorClave(logger, 
					mensajeErrorNoSePuedeAplicarOperacionIzquiera);
		}else{
			listadoDeCriterios.get(listadoDeCriterios.size()-1).setRelacional(operacion);
		}
		return this;
	}
	
	/**
	 * Nos devuelve la lista con los criterios.
	 * @return
	 */
	public List<FiltroCriterio> obtenerLasListas(){
		return listadoDeCriterios;
	}
	
}
